<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>创建线条</title>

    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>

    <style>
        *{
            padding: 0px;
            margin: 0px;
        }
        html{
            height: 100%;
        }
        body{
            display: flex;
            flex-wrap: wrap;
            align-items: center;
            justify-items: center;
            align-content: center;
            margin: 0px;
            width: 100%;
            height: 100%;
        }
        .main{
            font-size: 0.9rem;
            color: #0c111b;
            width: 100%;
            height: 100%;
            display: grid;
            grid-template-rows: auto auto 1fr
        }

        .form{
            display: grid;
            padding: 10px 20px;
            gap: 5px;
            grid-template-columns: 170px 170px 170px 170px;
            align-items: center;
        }

        .svg{
            padding: 20px;
        }

        svg{
            width: 100%;
            height: calc(100% - 5px);
        }
    </style>

</head>
<body>
    <div class="main">
        <div class="form">
            <div class="item">
                <label for="lineStartXY">线条开始坐标：</label>
                <input id="lineStartXY" type="text" style="width: 60px;" value="300 50">
            </div>
            <div class="item">
                <label for="lineEndXY">线条结束坐标：</label>
                <input id="lineEndXY" type="text" style="width: 60px;" value="800 400">
            </div>
            <div class="item">
                <label for="lineStyle">线条样式：</label>
                <select name="lineStyle">
                    <option value="0">线条</option>
                    <option value="1">短点</option>
                    <option value="2">短线</option>
                    <option value="3">长线</option>
                </select>
            </div>
            <div class="item">
                <label for="lineOrientation">线条方向：</label>
                <select name="lineOrientation">
                    <option value="0">水平</option>
                    <option value="1">垂直</option>
                </select>
            </div>
            <div class="item">
                <input id="beginArrows" type="checkbox" name="beginArrows"></input>
                <label for="beginArrows">开始箭头</label>
            </div>
            <div class="item">
                <input id="endArrows" type="checkbox" name="endArrows"></input>
                <label for="endArrows">结束箭头</label>
            </div>
            <div class="item">
                <label for="lineColor">线条颜色</label>
                <input type="color" id="lineColor" name="lineColor" value="#6482B9" />
            </div>
            <div class="item">
                <label for="lineGradientColor">线条渐变色</label>
                <input type="color" id="lineGradientColor" name="lineGradientColor" value="#EC3832" />
            </div>
            <div class="item">
                <input type="button" name="create" style="padding: 8px 20px;" value="创建">
            </div>
        </div>
        <hr>
        <div class="svg">
            <svg>  
            </svg>
        </div>
    </div>

    <script>
        $(function(){
            $("input[name='create']").on("click",create);

            function create(){
                var strLineStartXY = $("#lineStartXY").val();
                var strLineEndXY = $("#lineEndXY").val();
                var lineStyle=$("select[name='lineStyle']").val();
                var lineOrientation=$("select[name='lineOrientation']").val();
                var beginArrows=$("input[name='beginArrows']").prop("checked");
                var endArrows=$("input[name='endArrows']").prop("checked");
                var lineColor=$("#lineColor").val();
                var lineGradientColor=$("#lineGradientColor").val();
                var lines=[{startXY:[200,100],endXY:[400,400]},{startXY:[200,100],endXY:[600,400]},{startXY:[200,100],endXY:[20,400]}];
                if(strLineStartXY&&strLineEndXY.length>0&&strLineEndXY&&strLineEndXY.length>0){
                    lines.push({
                        startXY:strLineStartXY.split(' '),
                        endXY:strLineEndXY.split(' '),
                    })
                }
                render(lines,lineStyle,lineOrientation,beginArrows,endArrows,lineColor,lineGradientColor);
            }
        
            function render(lines,lineStyle,lineOrientation,beginArrows,endArrows,lineColor,lineGradientColor){
                
                var svg=$("div.svg svg");

                svg.empty();

                var defs = document.createElementNS("http://www.w3.org/2000/svg","defs");
                var marker_begin_arrow = document.createElementNS("http://www.w3.org/2000/svg","marker");
                marker_begin_arrow.setAttribute("id","begin_arrow");
                marker_begin_arrow.setAttribute("viewBox","0 0 10 10");
                marker_begin_arrow.setAttribute("markerWidth",10);
                marker_begin_arrow.setAttribute("markerHeight",7);
                marker_begin_arrow.setAttribute("refX",9);
                marker_begin_arrow.setAttribute("refY",3.5);
                marker_begin_arrow.setAttribute("orient","auto-start-reverse");
                var begin_arrow = document.createElementNS("http://www.w3.org/2000/svg","polygon");
                begin_arrow.setAttribute("points","0 0, 10 3.5, 0 7");
                begin_arrow.setAttribute("fill",lineColor||"#4facfe");
                marker_begin_arrow.appendChild(begin_arrow);

                var marker_end_arrow = document.createElementNS("http://www.w3.org/2000/svg","marker");
                marker_end_arrow.setAttribute("id","end_arrow");
                marker_end_arrow.setAttribute("viewBox","0 0 10 10");
                marker_end_arrow.setAttribute("markerWidth",10);
                marker_end_arrow.setAttribute("markerHeight",7);
                marker_end_arrow.setAttribute("refX",9);
                marker_end_arrow.setAttribute("refY",3.5);
                marker_end_arrow.setAttribute("orient","auto-start-reverse");
                var end_arrow = document.createElementNS("http://www.w3.org/2000/svg","polygon");
                end_arrow.setAttribute("points","0 0, 10 3.5, 0 7");
                end_arrow.setAttribute("fill",lineGradientColor||"#4facfe");
                marker_end_arrow.appendChild(end_arrow);

                // 定义线条渐变色
                var linear_gradient = document.createElementNS("http://www.w3.org/2000/svg","linearGradient");
                linear_gradient.setAttribute("id","linear_gradient");
                linear_gradient.setAttribute("x1","0%");
                linear_gradient.setAttribute("y1","0%");
                linear_gradient.setAttribute("x2","0%");
                linear_gradient.setAttribute("y2","100%");  //垂直方向渐变

                if(lineOrientation==0){
                    linear_gradient = document.createElementNS("http://www.w3.org/2000/svg","linearGradient");
                    linear_gradient.setAttribute("id","linear_gradient");
                    linear_gradient.setAttribute("x1","0%");
                    linear_gradient.setAttribute("y1","0%");
                    linear_gradient.setAttribute("x2","100%");  // 水方向线渐变
                    linear_gradient.setAttribute("y2","0%");
                }

                // 开始样式
                var begin_style = document.createElementNS("http://www.w3.org/2000/svg","stop");
                begin_style.setAttribute("offset","0%");
                begin_style.style["stop-color"]=lineColor;  // 颜色
                begin_style.style["stop-opacity"]=1;        // 不透明度
                // 结束样式
                var end_style = document.createElementNS("http://www.w3.org/2000/svg","stop");
                end_style.setAttribute("offset","100%");
                end_style.style["stop-color"]=lineGradientColor;  // 颜色
                end_style.style["stop-opacity"]=1;        // 不透明度

                linear_gradient.appendChild(begin_style);
                linear_gradient.appendChild(end_style);

                
                defs.appendChild(marker_begin_arrow);
                defs.appendChild(marker_end_arrow);
                defs.appendChild(linear_gradient);
                svg[0].appendChild(defs);

                lines.forEach((line)=>{
                    var bLine=new BrokenLine(line.startXY[0],line.startXY[1],line.endXY[0],line.endXY[1],2,lineColor);
                    bLine.lineStyle=parseInt(lineStyle)
                    bLine.orientation=parseInt(lineOrientation);
                    bLine.hasBeginArrows=beginArrows;
                    bLine.hasEndArrows=endArrows;
                    var bl = bLine.create();
                    svg[0].appendChild(bl);
                });
            }
        });

        (function(){
            var BrokenLine=window.BrokenLine=function(x1,y1,x2,y2,width,colore){
                this.x1=x1;
                this.y1=y1;
                this.x2=x2;
                this.y2=y2;
                this.width=width||2;
                this.colore=colore||"rgb(255,0,0)";
                this.lineStyle=0;   // 0 直线  1 断点  2 断线  3 长线
                this.orientation=0; // 0 水平  1 垂直 
                this.hasBeginArrows=false;
                this.hasEndArrows=false;
            };

            BrokenLine.prototype.create=function(){
                var xz1=this.x1;
                var xz2=this.x2;
                var yz1=this.y1;
                var yz2=this.y2;
                d = "M "+this.x1+","+this.y1;
                switch(this.orientation){
                    case 0:
                        d+= " c "+(this.x2-this.x1)/2+" 0, "+(this.x2-this.x1)/2+" "+(this.y2-this.y1)+", "+(this.x2-this.x1)+","+(this.y2-this.y1)
                        // d+= " c "+this.x1+","+(this.y1+this.y2)/2+" "+this.x1+","+this.y2+" "+this.x2+","+this.y2
                        break;
                    case 1:
                        d+= " c 0 "+(this.y2-this.y1)/2+", "+(this.x2-this.x1)+","+(this.y2-this.y1)/2+""+" "+(this.x2-this.x1)+","+(this.y2-this.y1)
                        // d+= " c 0 "+(this.y2-this.y1)/2+", "+(this.x2-this.x1)/4+",0"+" "+(this.x2-this.x1)/2+","+(this.y2-this.y1)/2
                        // d+= " c "+(this.x2-this.x1)/4+" 0"+","+(this.x2-this.x1)/4+" "+(this.y2-this.y1)/4+" ,"+(this.x2-this.x1)/4+" "+(this.y2-this.y1)/2
                        break;
                }

                var strokeDasharray="";
                switch(this.lineStyle){
                    case 1:
                        strokeDasharray=this.width+","+(this.width+2);
                        break;
                    case 2:
                        strokeDasharray=this.width*2+","+(this.width*2+2);
                        break;
                    case 3:
                        strokeDasharray=this.width*4+","+(this.width*4+2);
                        break;
                }

                //<polyline points="10,60 100,60 100,120 200,120" style="fill:none; stroke:rgb(255,0,0);stroke-width:2"></polyline>
                var polylineDom = document.createElementNS("http://www.w3.org/2000/svg","path");


                polylineDom.setAttribute("d",d);
                polylineDom.setAttribute("stroke-dasharray",strokeDasharray);
                polylineDom.setAttribute("style","fill:none;stroke:url(#linear_gradient);stroke-width:"+this.width+";");
                if(this.hasBeginArrows){
                    polylineDom.setAttribute("marker-start","url(#begin_arrow)")
                }
                if(this.hasEndArrows)
                    polylineDom.setAttribute("marker-end","url(#end_arrow)")
                return polylineDom;
            };
        }());
    </script>
</body>
</html>